/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */



package org.huihoo.orbas.orb.protocols.iiop;

/**
 * <p>Description: </p>
 * IIOP profiles creator.
 * <p>Copyright (c) 2002,2003</p>
 * <p>Company: <a href="http://www.huihoo.org/">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~mep">mep(mep@huihoo.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */


import com.cognition.util.j2me.Logger;
import com.cognition.util.j2me.SystemLogger;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.ServerSocketConnection;
import org.huihoo.orbas.orb.protocols.*;
import org.huihoo.orbas.orb.cdr.*;
//import org.omg.IIOP.*;

public class IiopProfileCreator extends ProfileCreator {
    private static Logger logger = SystemLogger.getLogger(SystemLogger.LOGGER_CONSOLE);
    public static final String LOG_TAG = "IiopProfileCreator";

    IiopChannel ch;
    private short port;
    
    public IiopProfileCreator(CDROutputStream out) {
        super(out);
        port = Iiop.TCP_PORT;
    }
    
    public IiopProfileCreator() {
        port = Iiop.TCP_PORT;
    }
    
    public Channel createChannel() {
    	if( ch == null ) {
    	    
    	    ch = new IiopChannel();
    	    
	        try {
    	        ch.setServerPort(port);
    	    }
    	    catch(java.io.IOException ex) {
                logger.debug(LOG_TAG, "first open attempt failed: " + ex.getMessage());
    	        //if failed,open a random socket
    	        try {
    	            ch.setServerPort(0);
    	        }
                catch(java.io.IOException e) {
                    logger.debug(LOG_TAG, "first open attempt failed: " + e.getMessage());
                    System.out.println("Cannot create server socket.");
                    e.printStackTrace();
                }
            }
    	}
        port = (short)ch.getServerPort();
    	
        return ch;
    }
    
    public org.omg.IOP.TaggedProfile[] createProfiles(byte[] objectKey, int version) {
        
        if(ch == null ) {
            createChannel();
        }
        
        org.omg.IOP.TaggedProfile[] profiles = new org.omg.IOP.TaggedProfile[1];
        org.omg.IOP.TaggedProfile profile;


        String localAddress = "localhost";

        try {

            localAddress = ch.getServerAddress();
        }
        catch(IOException e) {
            logger.error(LOG_TAG, "can't get local address. using default 'localhost'");
            e.printStackTrace();
            localAddress = "localhost";
            // return null;
        }

        logger.debug(LOG_TAG, "creating profiles for object at " +
                "host " + localAddress + ":" + port);

        
        switch(version) {
            case 10:
                org.omg.IIOP.ProfileBody_1_0 profile10 =
                        new org.omg.IIOP.ProfileBody_1_0();
                        
                profile10.iiop_version = new org.omg.IIOP.Version();
                profile10.iiop_version.major = 1;
                profile10.iiop_version.minor = 0;
                profile10.host = localAddress;
                profile10.port = port;
                profile10.object_key = objectKey;
                
                CDROutputStream out0 = new CDROutputStream(null);
                
                //byte flag cannot omitted here
                out0.write_boolean(false);
                org.omg.IIOP.ProfileBody_1_0Helper.write(out0, profile10);
                
                byte[] data0 = new byte[out0.getLength()];
                System.arraycopy(out0.getBuffer(), 0, data0 , 0, out0.getLength());
                profile = new org.omg.IOP.TaggedProfile(org.omg.IOP.TAG_INTERNET_IOP.value, data0);
                profiles[0] = profile;
                
                break;
                
            case 11:
                
                org.omg.IIOP.ProfileBody_1_1 profile11 = 
                        new org.omg.IIOP.ProfileBody_1_1();
                        
                profile11.iiop_version = new org.omg.IIOP.Version();
                profile11.iiop_version.major = 1;
                profile11.iiop_version.minor = 1;
                profile11.host = localAddress;
                profile11.port = port;
                profile11.object_key = objectKey;
                profile11.components = new org.omg.IOP.TaggedComponent[0];
                
                CDROutputStream out1 = new CDROutputStream(null);
                
                //byte flag cannot omitted here
                out1.write_boolean(false);
                org.omg.IIOP.ProfileBody_1_1Helper.write(out1, profile11);
                
                byte[] data1 = new byte[out1.getLength()];
                System.arraycopy(out1.getBuffer(), 0, data1 , 0, out1.getLength());
                profile = new org.omg.IOP.TaggedProfile(org.omg.IOP.TAG_INTERNET_IOP.value, data1);
                
                profiles[0] = profile;
                
                break;
                
            case 12:
                
                org.omg.IIOP.ProfileBody_1_1 profile12 = 
                        new org.omg.IIOP.ProfileBody_1_1();
                        
                profile12.iiop_version = new org.omg.IIOP.Version();
                profile12.iiop_version.major = 1;
                profile12.iiop_version.minor = 2;
                profile12.host = localAddress;
                profile12.port = port;
                profile12.object_key = objectKey;
                profile12.components = new org.omg.IOP.TaggedComponent[0];
                
                CDROutputStream out2 = new CDROutputStream(null);
                
                //byte flag cannot omitted here
                out2.write_boolean(false);
                org.omg.IIOP.ProfileBody_1_1Helper.write(out2, profile12);
                
                byte[] data2 = new byte[out2.getLength()];
                System.arraycopy(out2.getBuffer(), 0, data2 , 0, out2.getLength());
                profile = new org.omg.IOP.TaggedProfile(org.omg.IOP.TAG_INTERNET_IOP.value, data2);
                
                profiles[0] = profile;
                
                break;
                
            default:
                //error!
                
        }
        
        return profiles;
    }

}